package middleware

import (
    adminService "gin_http/internal/service/admin"
    commonError "gin_http/utils/common/error"
    "time"

    jwt "github.com/appleboy/gin-jwt/v3"
    "github.com/gin-gonic/gin"
    goJwt "github.com/golang-jwt/jwt/v5"
)

func Auth(authService *adminService.AuthService) (*jwt.GinJWTMiddleware, error) {
    return jwt.New(&jwt.GinJWTMiddleware{
        Realm:       "my zone",
        Key:         []byte("your-secret-key"),
        Timeout:     time.Hour * 24,
        MaxRefresh:  time.Hour * 24,
        IdentityKey: "id",

        Authenticator: func(c *gin.Context) (any, error) {
            var loginVals struct {
                Account  string `json:"account" binding:"required"`
                Password string `json:"password" binding:"required"`
            }
            if err := c.ShouldBindJSON(&loginVals); err != nil {
                return nil, jwt.ErrMissingLoginValues
            }

            user, err := authService.Login(loginVals.Account, loginVals.Password)
            if err != nil {
                return nil, jwt.ErrFailedAuthentication
            }

            return map[string]interface{}{"username": user.Username, "id": user.ID}, nil
        },

        IdentityHandler: func(c *gin.Context) any {
            claims := jwt.ExtractClaims(c)
            return claims
        },

        PayloadFunc: func(data any) goJwt.MapClaims {
            if v, ok := data.(map[string]interface{}); ok {
                return goJwt.MapClaims{
                    "id":       v["id"],
                    "username": v["username"],
                }
            }
            return goJwt.MapClaims{}
        },

        Unauthorized: func(c *gin.Context, code int, message string) {
            c.JSON(code, gin.H{"code": commonError.CodeUnauthorized, "message": message})
        },
    })
}

